#include "Channel.h"
#include "Connection.h"
Channel::Channel(EventLoop* loop, int fd)
    :fd_(fd),loop_(loop)
{
    // ep_ = loop_->ep();
}
// 返回关联的文件描述符
int Channel::fd() const
{
    return fd_;
}
// 返回是否已添加到 epoll 树
bool Channel::inpoll() const
{
    return inepoll_;
}
// 返回当前监视的事件集
uint32_t Channel::events() const
{
    return events_;
}
// 返回实际发生的事件集
uint32_t Channel::revents() const
{
    return revents_;
}

// 事件管理
// 设置使用边缘触发 (EPOLLET) 模式
void Channel::useet()
{
    events_ = events_ | EPOLLET;
}
// 启用读事件监视 (EPOLLIN)
void Channel::enablereading()
{
    events_ = events_ | EPOLLIN;
    // ep_->updatechannel(this);
    loop_->ep()->updatechannel(this);
}
// 标记已添加到 epoll 树
void Channel::setinepoll()
{
    inepoll_ = true;
}

void Channel::setrevents(uint32_t ev)
{
    revents_ = ev;
}

void Channel::handleevent()
{
    if (revents_ & EPOLLRDHUP)
    {
        // printf("client(eventfd=%d)disconnected\n", fd_);
        // close(fd_);
        closecallback_();
    }
    else if (revents_ & (EPOLLIN | EPOLLPRI))
    {
        readcallback_();
    }
    else if (revents_ & EPOLLOUT)
    {
    }
    else
    { // 其他事件都视为错误
        // printf("else error\n");
        // close(fd_);
        errorcallback_();
    }
}

Channel::~Channel()
{
}

// void Channel::newconnection(Socket* servsock)
// {
//     InetAddress clientaddr;
//     /*
//     注意：只能new 否则析构函数会关闭fd
//     还有，这里new出来的对象没有释放，这个问题以后再解决
//     */
//     Socket *clientsock = new Socket(servsock->accept(clientaddr));

//     if (clientsock->fd() < 0)
//     {
//         perror("accept() failed");
//         return;
//     }

//     Connection *conn = new Connection(loop_,clientsock);

//     printf("New client connected: %s:%d\n", clientaddr.ip().c_str(), clientaddr.port());
// }
void Channel::onmessage()
{
    char buffer[1024];

    while (true)
    {                                   // 非阻塞IO循环读取
        bzero(&buffer, sizeof(buffer)); // 清空缓冲区

        ssize_t nread = read(fd_, buffer, sizeof(buffer));

        if (nread > 0)
        { // 成功读取数据
            printf("recv(eventfd=%d):%s\n", fd_, buffer);

            for (size_t i = 0; i < (size_t)nread; i++)
            {
                buffer[i] = toupper(buffer[i]);
            }

            send(fd_, buffer, nread, 0); // 原样回发（使用nread而非strlen）
        }
        else if (nread == -1 && errno == EINTR)
        { // 被信号中断
            continue;
        }
        else if (nread == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
        { // 非阻塞无数据
            break;
        }
        else if (nread == 0)
        { // 客户端断开连接
            // printf("client(eventfd=%d) disconnected.\n", fd_);
            // close(fd_);
            closecallback_();
            break;
        }
    }
}

void Channel::setreadcallback(std::function<void()> f)
{
    readcallback_ = f;
}

void Channel::setclosecallback(std::function<void()> f)
{
    closecallback_ = f;
}
void Channel::seterrorcallback(std::function<void()> f)
{
    errorcallback_ = f;
}